package com.boesch.electroOffice.presentation.invoice;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.portlet.PortletSession;

import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.boesch.electroOffice.business.businessObject.InvoiceBusinessObject;
import com.boesch.electroOffice.business.common.BusinessException;
import com.boesch.electroOffice.dataaccess.common.IllegalDataAccessException;
import com.boesch.electroOffice.model.enums.SubfunctionIdentifier;
import com.boesch.electroOffice.model.messerli.Invoice;
import com.boesch.electroOffice.utils.MessageUtils;
import com.boesch.electroOffice.utils.PortletUtils;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;

/**
 * This class controls all the data is needed 
 * in the above package com.boesch.electroOffice.presentation.invoice
 * 
 * For more details about the package layering have a look at the documentation
 * of the project electroOffice or the project object model pom.xml
 * 
 * @author Ralph Koster
 *
 */
@Controller
@ManagedBean
@SessionScoped
public class InvoiceListController implements Serializable {

	private static final long serialVersionUID = 5940182433871230756L;
	private static final Log log = LogFactoryUtil.getLog(InvoiceListController.class);
	
	@Autowired
	private InvoiceBusinessObject invoiceBusinessObject;
	@Autowired
	private InvoiceNavigationController navigationController;
	
	private List<Invoice> invoices;
	private List<Invoice> filteredInvoices;
	
	private Invoice selectedInvoice;
	
	private boolean invoicesInitialized = false;
	
	public List<Invoice> getInvoices() {
		PortletSession session = PortletUtils.getPortletSession();
		String key = (String)session.getAttribute("key");
		if(null == invoices || !invoicesInitialized) {
			try {
				invoices = invoiceBusinessObject.readAllInvoicesFromDataaccess();
				invoicesInitialized = true;
			} catch (BusinessException e) {
				log.error("Failed to load the list of invoices.", e.getCause());
				MessageUtils.addErrorMessage("Fehler beim lesen der Rechnungen.");
			} catch (IllegalDataAccessException e) {
				log.error("Failed to load the list of invoices.", e.getCause());
				MessageUtils.addErrorMessage("Fehler beim lesen der Rechnungen.");
			} 
		}
		
		if(null != key) {
			if(key.equals(SubfunctionIdentifier.OPEN_INVOICES.getValue())) {
				return getOpenInvoices();
			} else if(key.equals(SubfunctionIdentifier.DUE_INVOICES.getValue())) {
				return getDueInvoices();
			} else if(key.equals(SubfunctionIdentifier.PAYED_INVOICES.getValue())) {
				return getPayedInvoices();
			} else {
				return invoices;
			}
		} else {
			return invoices;
		}
	}
	
	public void navigateToInvoiceView(ActionEvent actionEvent) {
		setSessionAttributeSelectedInvoiceId();
		String navigationPath = "/jsf/invoice/invoice_detail.xhtml";
		navigateToPath(navigationPath);
	}
	
	public List<Invoice> getFilteredInvoices() {
		return filteredInvoices;
	}

	public void setFilteredInvoices(List<Invoice> filteredInvoices) {
		this.filteredInvoices = filteredInvoices;
	}
	
	public Invoice getSelectedInvoice() {  
        return selectedInvoice;  
    }
	
    public void setSelectedInvoice(Invoice selectedInvoice) {
        this.selectedInvoice = selectedInvoice;  
    }
    
    public boolean isOneInvoiceSelected() {
    	boolean returnValue = false;
    	if(null != selectedInvoice) {
    		returnValue = true;
    	}
    	return returnValue;
    }
    
    private List<Invoice> getOpenInvoices() {
    	List<Invoice> openInvoices = new ArrayList<Invoice>();
		for(Invoice invoice : invoices) {
			LocalDate now = new LocalDate();
			if(null != invoice.getInvoiceDueDate()) {
				if(invoice.getInvoiceDueDate().isAfter(now)
						&& null == invoice.getInvoiceBookingDate()) {
					openInvoices.add(invoice);
				}
			}
		}
		return openInvoices;
    }

	private List<Invoice> getDueInvoices() {
		List<Invoice> dueInvoices = new ArrayList<Invoice>();
		for(Invoice invoice : invoices) {
			LocalDate now = new LocalDate();
			if(null != invoice.getInvoiceDueDate()) {
				if(invoice.getInvoiceDueDate().isBefore(now)
						&& null == invoice.getInvoiceBookingDate()) {
					dueInvoices.add(invoice);
				}
			}
		}
		return dueInvoices;
	}

	private List<Invoice> getPayedInvoices() {
		List<Invoice> payedInvoices = new ArrayList<Invoice>();
		for(Invoice invoice : invoices) {
			if(null != invoice.getInvoiceBookingDate()) {
				payedInvoices.add(invoice);
			}
		}
		return payedInvoices;
	}
	
	private void navigateToPath(String navigationPath) {
		if(null != selectedInvoice) {
			String invoiceNumber = selectedInvoice.getInvoiceNumber();
			PortletSession session = PortletUtils.getPortletSession();
			session.setAttribute("invoiceNumber", invoiceNumber);
			navigationController.setNavigationPath(navigationPath);
		} else {
			MessageUtils.addErrorMessage("Bitte selektieren Sie einen Auftrag aus der Liste!");
		}
	}
	
	private void setSessionAttributeSelectedInvoiceId() {
		if(null != selectedInvoice) {
			PortletSession session = PortletUtils.getPortletSession();
			session.setAttribute("invoiceNumber", selectedInvoice.getInvoiceNumber());
		}
	}
}

